import axios from 'axios'
import { AxiosCanceler } from './axiosCancel.js'
import { cloneDeep } from '@/utils/common.js'
import { isFunction } from '@/utils/is.js'

/**
* @description axios模块
* @param {Object} options
*/
export class VAxios {
  constructor(options) {
    this.options = options
    // 创建axios实例
    this.axiosInstance = axios.create(options)
    this.setupInterceptors()
  }

  /**
  * @description 创建axios实例
  * @param {Object}
  */
  createAxios(config) {
    this.axiosInstance = axios.create(config)
  }

  /**
  * @description 获取axios实例
  * @returns {Object}
  */
  getAxios() {
    return this.axiosInstance
  }

  /**
  * @description 获取options中的转化对象
  * @returns {Object} transform
  */
  getTransform() {
    const { transform } = this.options
    return transform
  }

  /**
  * @description 重新配置axios
  * @param {Object} config
  */
  setConfigAxios(config) {
    if (!this.axiosInstance) return
    this.createAxios(config)
  }

  /**
  * @description 设置通用header
  * @param {any} header
  */
  setHeader(headers) {
    if (!this.axiosInstance) return
    Object.assign(this.axiosInstance.defaults.headers, headers)
  }

  /**
  * @description 拦截器配置--请求拦截器+响应拦截器
  */
  setupInterceptors() {
    const transform = this.getTransform()
    if (!transform) return
    const { requestInterceptors, responseInterceptors } = transform

    const axiosCanceler = new AxiosCanceler()

    // 请求拦截器配置处理
    this.axiosInstance.interceptors.request.use(config => {
      const { headers: { ignoreCancelToken } = { ignoreCancelToken: false } } = config
      !ignoreCancelToken && axiosCanceler.addPending(config)
      if (requestInterceptors && isFunction(requestInterceptors)) {
        config = requestInterceptors(config)
      }
      return config
    }, null)

    // 请求拦截器错误捕获

    // 响应结果拦截器处理
    this.axiosInstance.interceptors.response.use(res => {
      res && axiosCanceler.removePending(res.config)
      if (responseInterceptors && isFunction(responseInterceptors)) {
        res = responseInterceptors(res)
      }
      return res
    }, null)

    // // 响应结果拦截器错误捕获
    // responseInterceptorsCatch && isFunction(responseInterceptorsCatch) && this.axiosInstance.interceptors.response.use(null, responseInterceptorsCatch)
  }

  /**
  * @description request请求方法
  */
  request(config, options) {
    let conf = cloneDeep(config)
    const transform = this.getTransform()
    const { beforeRequestHook, transformRequest, requestCatch } = transform || {}
    const { requestOptions } = this.options
    // 合并对象
    const opt = Object.assign({}, requestOptions, options)
    // 处理请求前的config
    if (beforeRequestHook && isFunction(beforeRequestHook)) {
      conf = beforeRequestHook(conf, opt)
    }
    return new Promise((resolve, reject) => {
      this.axiosInstance
        .request(conf)
        .then(res => {
          // 请求是否被取消
          const isCancel = axios.isCancel(res)
          if (transformRequest && isFunction(transformRequest) && !isCancel) {
            const ret = transformRequest(res, opt)
            return resolve(ret)
          }
          reject(res)
        }).catch(error => {
          // 捕获响应错误
          if (requestCatch && isFunction(requestCatch)) {
            reject(error)
          }
          reject(error)
        })
    })
  }

  /**
  * @description 并发请求
  * @param {Array} requests
  */
  async all(requests) {
    // if (!requests.length) return
    // for (let i = 0, length = requests.length; i < length; i++) {
    //   const requsetItem = requests[i]
    //   const requestMethod = await this.request(requsetItem.config, requsetItem.options)
    //   console.log(requestMethod)
    //   requestMethods.push(requestMethod)
    // }
    // return new Promise((resolve, reject) => {
    //   axios.all(requestMethods).then(axios.spread((...args) => {
    //     resolve(...args)
    //   })).catch(error => reject(error))
    // })
  }
}

export default VAxios
